// Learn TypeScript:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html
export default class MsgMgr{
    private static _list:Object = {};
    private static _targets:Object = {};
    private static _once:Object = {};
    private static _onceTarget:Object = {};
    public static on<T extends Function>(type: string, callback: T, target: any)
    {
        if(!this._list[type])
        {
            this._list[type] = [callback];
            this._targets[type] = [target];
        }else
        {
            if(this._list[type].indexOf(callback)==-1||this._targets[type].indexOf(target)==-1)
            {
                this._list[type].push(callback);
                this._targets[type].push(target);
            }
        }
    }
    public static once<T extends Function>(type: string, callback: T, target: any)
    {
        if(!this._once[type])
        {
            this._once[type] = [callback];
            this._onceTarget[type] = [target];
        }else
        {
            if(this._once[type].indexOf(callback)==-1||this._onceTarget[type].indexOf(target)==-1)
            {
                this._once[type].push(callback);
                this._onceTarget[type].push(target);
            }
        }
    }
    public static off(type: string, callback?: Function, target?: any): void
    {
        if(callback)
        {
            if(this._list[type])
            {
                for(var i:number=0;i<this._list[type].length;i++)
                {
                    if(this._list[type][i]==callback&&this._targets[type][i]==target)
                    {
                        this._list[type].splice(i,1);
                        this._targets[type].splice(i,1);
                        break;
                    }
                }
            }
            if(this._once[type])
            {
                for(var i:number=0;i<this._once[type].length;i++)
                {
                    if(this._once[type][i]==callback&&this._onceTarget[type][i]==target)
                    {
                        this._once[type].splice(i,1);
                        this._onceTarget[type].splice(i,1);
                        break;
                    }
                }
            }
        }else
        {
            delete this._list[type];
            delete this._once[type];
            delete this._targets[type];
            delete this._onceTarget[type];
        }
    }

    public static emit(type: string, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, arg6?: any): void
    {
        if(this._list[type])
        {
            let len:number = this._list[type].length;
            for(let i:number=0;i<len;i++)
            {
                // try{
                    this._list[type][i].call(this._targets[type][i],arg1,arg2,arg3,arg4,arg5,arg6);
                // }catch(e)
                // {
                //     cc.warn("emit err",type)
                // }
            }
        }
        if(this._once[type])
        {
            let len:number = this._once[type].length;
            for(let i:number=0;i<len;i++)
            {
                this._once[type][i].call(this._onceTarget[type][i],arg1,arg2,arg3,arg4,arg5,arg6);
            }
            delete this._once[type];
            delete this._onceTarget[type];
        }
    }
}
